from flask import abort

from flask_restful import Resource, reqparse, fields, marshal, marshal_with
from flask_httpauth import HTTPBasicAuth
from app.models.todo import Todo
from ext import db, jwt
from flask_jwt_extended import jwt_required

# auth = HTTPBasicAuth()

# 格式化输出数据，输出的json格式如下
todo_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'description': fields.String,
    'done': fields.Boolean,
    'uri': fields.Url(absolute=True)
}

todo_list_fields = {
    'count': fields.Integer,
    'todos': fields.List(fields.Nested(todo_fields)),
}


class TaskListAPI(Resource):
    # HTTP 基本身份验
    # decorators = [auth.login_required]

    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('title', type=str, required=True, help='No task title provided', location='json')
        self.reqparse.add_argument('description', type=str, required=True, help='=No mission description',
                                   location='json')
        self.reqparse.add_argument('done', type=int, default=0, location='json')
        super(TaskListAPI, self).__init__()

    # 查看所有任务列表
    # 需要验证token
    @jwt_required()
    def get(self):
        tasks_list = Todo.query.all()
        return marshal({
            'count': len(tasks_list),
            'tasks': [marshal(t, todo_fields) for t in tasks_list]
        }, todo_list_fields)

    # 创建新任务
    # todo_fields的json格式化输出
    @marshal_with(todo_fields)
    # 需要验证token
    @jwt_required()
    def post(self):
        # if not request.json or not 'title' in request.json:
        #     abort(400)
        # param strict: if req includes args not in parser, throw 400 BadRequest exception
        args = self.reqparse.parse_args(strict=True)
        todo = Todo(**args)
        db.session.add(todo)
        db.session.commit()
        return todo


class TaskAPI(Resource):
    # HTTP 基本身份验
    # decorators = [auth.login_required]

    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('title', type=str, location='json')
        self.reqparse.add_argument('description', type=str, location='json')
        self.reqparse.add_argument('done', type=bool, location='json')
        super(TaskAPI, self).__init__()

    # 查看某个任务
    @marshal_with(todo_fields)
    # 需要验证token
    @jwt_required()
    def get(self, id):
        if not id:
            abort(400)
        todo = Todo.query.get_or_404(id)
        return todo

    # 更新某个任务
    @marshal_with(todo_fields)
    # 需要验证token
    @jwt_required()
    def put(self, id):
        if not id:
            abort(400)
        post = Todo.query.get_or_404(id)
        args = self.reqparse.parse_args(strict=True)
        if args["title"]:
            post.title = args["title"]
        if args["description"]:
            post.description = args["description"]
        if args["done"]:
            post.done = args["done"]

        # 第二种实现方式
        # if 'title' in request.json:
        #     post.title = request.json['title']
        #
        # if 'description' in request.json:
        #     post.description = request.json['description']
        #
        # if 'done' in request.json:
        #     post.done = request.json['done']
        db.session.add(post)
        db.session.commit()
        return post, 201

    # 删除某个任务
    @marshal_with(todo_fields)
    # 需要验证token
    @jwt_required()
    def delete(self, id):
        if not id:
            abort(400)
        post = Todo.query.get_or_404(id)
        db.session.delete(post)
        db.session.commit()
        # return post
        return {"code": 204, 'message': "删除成功"}, 204
